<!DOCTYPE html>
<html lang=zh>
<head>
  <meta charset="utf-8">
  
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="renderer" content="webkit">
  <meta http-equiv="Cache-Control" content="no-transform" />
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="format-detection" content="telephone=no,email=no,adress=no">
  <!-- Color theme for statusbar -->
  <meta name="theme-color" content="#000000" />
  <!-- 强制页面在当前窗口以独立页面显示,防止别人在框架里调用页面 -->
  <meta http-equiv="window-target" content="_top" />
  
  
  <title>前端性能优化 | 雨落</title>
  <meta name="description" content="前端性能优化 最小化HTTP请求：最终用户响应的时间的80%用于前端，大部分时间都与下载页面中的所有组件有关：图像，样式表，脚本，Flash等  组合文件：将所有脚本合成一个脚本，将所有的样式组合成一个css样式表来减少http请求次数 CSS Sprites是减少图像请求数量的首选方法。将背景图像合并为单个图像，并使用CSSbackground-image和background-position">
<meta property="og:type" content="article">
<meta property="og:title" content="前端性能优化">
<meta property="og:url" content="https://gitee.com/Yu-Luoboke/2021/04/23/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/index.html">
<meta property="og:site_name" content="雨落">
<meta property="og:description" content="前端性能优化 最小化HTTP请求：最终用户响应的时间的80%用于前端，大部分时间都与下载页面中的所有组件有关：图像，样式表，脚本，Flash等  组合文件：将所有脚本合成一个脚本，将所有的样式组合成一个css样式表来减少http请求次数 CSS Sprites是减少图像请求数量的首选方法。将背景图像合并为单个图像，并使用CSSbackground-image和background-position">
<meta property="og:locale" content="zh_CN">
<meta property="og:image" content="https://gitee.com/blog/images/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%AE%9E%E6%88%98.jpg">
<meta property="og:image" content="https://gitee.com/blog/images/%E6%B7%98%E5%AE%9D.png">
<meta property="og:image" content="https://gitee.com/blog/images/%E6%94%AF%E4%BB%98%E5%AE%9D.png">
<meta property="article:published_time" content="2021-04-23T02:39:29.000Z">
<meta property="article:modified_time" content="2021-04-23T07:53:58.453Z">
<meta property="article:author" content="lianghongming">
<meta name="twitter:card" content="summary">
<meta name="twitter:image" content="https://gitee.com/blog/images/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%AE%9E%E6%88%98.jpg">
  <!-- Canonical links -->
  <link rel="canonical" href="https://gitee.com/Yu-Luoboke/2021/04/23/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/index.html">
  
    <link rel="alternate" href="/atom.xml" title="雨落" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png" type="image/x-icon">
  
  
<link rel="stylesheet" href="/blog/css/style.css">

  
  
  
  
<meta name="generator" content="Hexo 5.2.0"></head>


<body class="main-center" itemscope itemtype="http://schema.org/WebPage">
  <header class="header" itemscope itemtype="http://schema.org/WPHeader">
  <div class="slimContent">
    <div class="navbar-header">
      
      
      <div class="profile-block text-center">
        <a id="avatar" href="http://yu-luoboke.gitee.io/blog" target="_blank">
          <img class="img-circle img-rotate" src="/blog/images/avatar.jpg" width="200" height="200">
        </a>
        <h2 id="name" class="hidden-xs hidden-sm">雨落</h2>
        <h3 id="title" class="hidden-xs hidden-sm hidden-md">前端开发-奋斗青年</h3>
        <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i> GuangZhou, China</small>
      </div>
      
      <div class="search" id="search-form-wrap">

    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="搜索" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i class="icon icon-search"></i></button>
            </span>
        </div>
    </form>
    <div class="ins-search">
  <div class="ins-search-mask"></div>
  <div class="ins-search-container">
    <div class="ins-input-wrapper">
      <input type="text" class="ins-search-input" placeholder="想要查找什么..." x-webkit-speech />
      <button type="button" class="close ins-close ins-selectable" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
    </div>
    <div class="ins-section-wrapper">
      <div class="ins-section-container"></div>
    </div>
  </div>
</div>


</div>
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>
    <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
      <ul class="nav navbar-nav main-nav menu-highlight">
        
        
        <li class="menu-item menu-item-home">
          <a href="/blog/.">
            
            <i class="icon icon-home-fill"></i>
            
            <span class="menu-title">首页</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives">
            
            <i class="icon icon-archives-fill"></i>
            
            <span class="menu-title">归档</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-categories">
          <a href="/blog/categories">
            
            <i class="icon icon-folder"></i>
            
            <span class="menu-title">分类</span>
          </a>
        </li>
        
        
        <li class="menu-item menu-item-tags">
          <a href="/blog/tags">
            
            <i class="icon icon-tags"></i>
            
            <span class="menu-title">标签</span>
          </a>
        </li>
        
      </ul>
      
	
    <ul class="social-links">
    	
        <li><a href="http://yu-luoboke.gitee.io/blog" target="_blank" title="Github" ><i class="icon icon-github"></i></a></li>
        
    </ul>

    </nav>
  </div>
</header>

  
    <aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">公告</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">
                <p>欢迎交流与分享经验!</p>
            </div>
        </div>
    </div>
</div>

    
      
  <div class="widget">
    <h3 class="widget-title">分类</h3>
    <div class="widget-body">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Git/">Git</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/HTML-CSS/">HTML + CSS</a><span class="category-list-count">7</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/JVM%EF%BC%88Java%E8%99%9A%E6%8B%9F%E6%9C%BA%EF%BC%89-%E5%9E%83%E5%9C%BE%E5%9B%9E%E6%94%B6%E7%AE%97%E6%B3%95/">JVM（Java虚拟机）-垃圾回收算法</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Node/">Node</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Project/">Project</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/React/">React</a><span class="category-list-count">4</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/SVN/">SVN</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/Vue-typescript/">Vue-typescript</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/gitee/">gitee</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/iOS/">iOS</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/js/">js</a><span class="category-list-count">12</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/vue/">vue</a><span class="category-list-count">13</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/web-serve%E9%9D%99%E6%80%81%E8%B5%84%E6%BA%90%E6%9C%8D%E5%8A%A1%E5%99%A8/">web serve静态资源服务器</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/webpack/">webpack</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E5%89%8D%E7%AB%AF%E8%87%AA%E5%8A%A8%E5%8C%96/">前端自动化</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E5%B0%8F%E7%A8%8B%E5%BA%8F/">小程序</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E7%A7%BB%E5%8A%A8%E7%AB%AF/">移动端</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E7%BB%8F%E9%AA%8C/">经验</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a><span class="category-list-count">4</span></li></ul>
    </div>
  </div>


    
      

    
      
    
      
  <div class="widget">
    <h3 class="widget-title">归档</h3>
    <div class="widget-body">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2024/04/">四月 2024</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2023/11/">十一月 2023</a><span class="archive-list-count">8</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2023/09/">九月 2023</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/12/">十二月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/08/">八月 2022</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/07/">七月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/06/">六月 2022</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/04/">四月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2022/01/">一月 2022</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/12/">十二月 2021</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/11/">十一月 2021</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/10/">十月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/04/">四月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/03/">三月 2021</a><span class="archive-list-count">3</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/02/">二月 2021</a><span class="archive-list-count">1</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2021/01/">一月 2021</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/blog/archives/2020/12/">十二月 2020</a><span class="archive-list-count">15</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">最新文章</h3>
    <div class="widget-body">
      <ul class="recent-post-list list-unstyled no-thumbnail">
        
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/HTML-CSS/">HTML + CSS</a>
              </p>
              <p class="item-title">
                <a href="/blog/2024/04/15/%E6%8B%96%E5%8A%A8%E5%92%8C%E7%82%B9%E5%87%BB%E5%BC%B9%E7%AA%97/" class="title">拖动和点击弹窗</a>
              </p>
              <p class="item-date">
                <time datetime="2024-04-15T12:22:06.000Z" itemprop="datePublished">2024-04-15</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/html%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">html面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:58:27.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/css%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">css面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:57:17.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/js%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">js面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:37:30.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/blog/categories/%E9%9D%A2%E8%AF%95%E9%A2%98/">面试题</a>
              </p>
              <p class="item-title">
                <a href="/blog/2023/11/29/%E9%9D%A2%E8%AF%95%E9%A2%98/" class="title">面试题</a>
              </p>
              <p class="item-date">
                <time datetime="2023-11-29T15:29:49.000Z" itemprop="datePublished">2023-11-29</time>
              </p>
            </div>
          </li>
          
      </ul>
    </div>
  </div>
  

    
  </div>
</aside>

  
  
<main class="main" role="main">
  <div class="content">
  <article id="post-前端性能优化" class="article article-type-post" itemscope itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      
        
  
    <h1 class="article-title" itemprop="name">
      前端性能优化
    </h1>
  

      
      <div class="article-meta">
        <span class="article-date">
    <i class="icon icon-calendar-check"></i>
	<a href="/blog/2021/04/23/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" class="article-date">
	  <time datetime="2021-04-23T02:39:29.000Z" itemprop="datePublished">2021-04-23</time>
	</a>
</span>
        
  <span class="article-category">
    <i class="icon icon-folder"></i>
    <a class="article-category-link" href="/blog/categories/js/">js</a>
  </span>

        

        

        <span class="post-comment"><i class="icon icon-comment"></i> <a href="/blog/2021/04/23/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/#comments" class="article-comment-link">评论</a></span>
        
      </div>
    </div>
    <div class="article-entry marked-body" itemprop="articleBody">
      
        <h3 id="前端性能优化"><a href="#前端性能优化" class="headerlink" title="前端性能优化"></a>前端性能优化</h3><ul>
<li><p>最小化HTTP请求：最终用户响应的时间的80%用于前端，大部分时间都与下载页面中的所有组件有关：图像，样式表，脚本，Flash等</p>
<ul>
<li>组合文件：将所有脚本合成一个脚本，将所有的样式组合成一个css样式表来减少http请求次数</li>
<li>CSS Sprites是减少图像请求数量的首选方法。将背景图像合并为单个图像，并使用CSSbackground-image和background-position属性显示所需的图像段</li>
<li>将使用到的数据整合在一起，让后端返回少量接口达到渲染整个页面的目的</li>
<li>减少DNS查询次数：DNS查询也消耗响应时间，若网页来自不同的域名（domain），则客户端首次解析这些域名消耗一定的时间，一般对首次访问的速度有影响。具体的做法：减少域名数量</li>
<li>DNS缓存：DNS查询过程大约消耗20毫秒，在DNS查询过程中，浏览器什么都不会做，保持空白。如果DNS查询很多，网页性能会受到很大影响，因此需要用到DNS缓存。 不同浏览器的缓存机制不同： IE对DNS记录默认的缓存时间为30分钟，Firefox对DNS记录默认的缓存时间为1分钟，Chrome对DNS记录默认的缓存时间为1分钟。</li>
</ul>
</li>
<li><p>使用HTTP2</p>
<ul>
<li>HTTP2 相比 HTTP1.1 有如下几个优点：<ul>
<li>解析速度快<ul>
<li>服务器解析 HTTP1.1 的请求时，必须不断地读入字节，直到遇到分隔符 CRLF 为止。而解析 HTTP2 的请求就不用这么麻烦，因为 HTTP2 是基于帧的协议，每个帧都有表示帧长度的字段</li>
</ul>
</li>
<li>多路复用<ul>
<li>HTTP1.1 如果要同时发起多个请求，就得建立多个 TCP 连接，因为一个 TCP 连接同时只能处理一个 HTTP1.1 的请求。在 HTTP2 上，多个请求可以共用一个 TCP 连接，这称为多路复用。同一个请求和响应用一个流来表示，并有唯一的流 ID 来标识。 多个请求和响应在 TCP 连接中可以乱序发送，到达目的地后再通过流 ID 重新组建</li>
</ul>
</li>
<li>首部压缩<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 请求1</span></span><br><span class="line">:authority: unpkg.zhimg.com</span><br><span class="line">:method: GET</span><br><span class="line">:path: <span class="regexp">/za-js-sdk@2.16.0/</span>dist/zap.js</span><br><span class="line">:scheme: https</span><br><span class="line">accept: *<span class="comment">/*</span></span><br><span class="line"><span class="comment">accept-encoding: gzip, deflate, br</span></span><br><span class="line"><span class="comment">accept-language: zh-CN,zh;q=0.9</span></span><br><span class="line"><span class="comment">cache-control: no-cache</span></span><br><span class="line"><span class="comment">pragma: no-cache</span></span><br><span class="line"><span class="comment">referer: https://www.zhihu.com/</span></span><br><span class="line"><span class="comment">sec-fetch-dest: script</span></span><br><span class="line"><span class="comment">sec-fetch-mode: no-cors</span></span><br><span class="line"><span class="comment">sec-fetch-site: cross-site</span></span><br><span class="line"><span class="comment">user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">// 请求2</span></span><br><span class="line"><span class="comment">:authority: zz.bdstatic.com</span></span><br><span class="line"><span class="comment">:method: GET</span></span><br><span class="line"><span class="comment">:path: /linksubmit/push.js</span></span><br><span class="line"><span class="comment">:scheme: https</span></span><br><span class="line"><span class="comment">accept: */</span>*</span><br><span class="line">accept-encoding: gzip, deflate, br</span><br><span class="line">accept-language: zh-CN,zh;q=<span class="number">0.9</span></span><br><span class="line">cache-control: no-cache</span><br><span class="line">pragma: no-cache</span><br><span class="line">referer: https:<span class="comment">//www.zhihu.com/</span></span><br><span class="line">sec-fetch-dest: script</span><br><span class="line">sec-fetch-mode: no-cors</span><br><span class="line">sec-fetch-site: cross-site</span><br><span class="line">user-agent: Mozilla/<span class="number">5.0</span> (Windows NT <span class="number">6.1</span>; Win64; x64) AppleWebKit/<span class="number">537.36</span> (KHTML, like Gecko) Chrome/<span class="number">80.0</span><span class="number">.3987</span><span class="number">.122</span> Safari/<span class="number">537.36</span></span><br></pre></td></tr></table></figure>
从上面两个请求可以看出来，有很多数据都是重复的。如果可以把相同的首部存储起来，仅发送它们之间不同的部分，就可以节省不少的流量，加快请求的时间</li>
</ul>
</li>
</ul>
</li>
<li><p>使用服务端渲染：</p>
<ul>
<li>客户端渲染: 获取 HTML 文件，根据需要下载 JavaScript 文件，运行文件，生成 DOM，再渲染。服务端渲染：服务端返回 HTML 文件，客户端只需解析 HTML</li>
</ul>
</li>
<li><p>使用内容交付网络（CDN）</p>
<ul>
<li>内容交付网络（CDN）是分布在多个位置的Web服务器的集合，目的是将内容更有效地交付给用户。选择用于向特定用户传送内容的服务器通常基于网络邻近性的度量。例如，选择网络跳数最少的服务器或响应时间最快的服务器</li>
<li>将静态内容从其应用程序Web服务器移至CDN，能将最终用户的响应时间缩短了20％或更多</li>
</ul>
</li>
<li><p>善用缓存，不重复加载相同的资源（目前还不了解清楚）</p>
<ul>
<li>为了避免用户每次访问网站都得请求文件，我们可以通过添加 Expires 或 max-age 来控制这一行为。Expires 设置了一个时间，只要在这个时间之前，浏览器都不会请求文件，而是直接使用缓存。而 max-age 是一个相对时间，建议使用 max-age 代替 Expires</li>
</ul>
</li>
<li><p>压缩文件</p>
</li>
<li><p>图片延迟加载：在页面中，先不给图片设置路径，只有当图片出现在浏览器的可视区域时，才去加载真正的图片，这就是延迟加载</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 具体实现</span></span><br><span class="line">&lt;img data-src=<span class="string">&quot;./images/1.jpg&quot;</span> alt=<span class="string">&quot;&quot;</span> /&gt;  <span class="comment">//  data-src：自定义属性，可以是任何值，这里一般是填写图片的路径</span></span><br><span class="line">&lt;img data-src=<span class="string">&quot;./images/2.jpg&quot;</span> alt=<span class="string">&quot;&quot;</span> /&gt;</span><br><span class="line">&lt;img data-src=<span class="string">&quot;./images/3.jpg&quot;</span> alt=<span class="string">&quot;&quot;</span> /&gt;</span><br><span class="line">&lt;img data-src=<span class="string">&quot;./images/4.jpg&quot;</span> alt=<span class="string">&quot;&quot;</span> /&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment">// getBoundingClientRect()//获取元素的大小及相对于视口的位置</span></span><br><span class="line"> <span class="keyword">var</span> imgs = <span class="built_in">document</span>.querySelectorAll(<span class="string">&#x27;img&#x27;</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">//用来判断bound.top&lt;=clientHeight的函数，返回一个bool值</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">isIn</span>(<span class="params">el</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> bound = el.getBoundingClientRect();</span><br><span class="line">    <span class="keyword">var</span> clientHeight = <span class="built_in">window</span>.innerHeight;</span><br><span class="line">    <span class="keyword">return</span> bound.top &lt;= clientHeight;</span><br><span class="line">&#125; </span><br><span class="line"><span class="comment">//检查图片是否在可视区内，如果不在，则加载</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">check</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">Array</span>.from(imgs).forEach(<span class="function"><span class="keyword">function</span>(<span class="params">el</span>)</span>&#123;</span><br><span class="line">        <span class="keyword">if</span>(isIn(el))&#123;</span><br><span class="line">            loadImg(el);</span><br><span class="line">        &#125;</span><br><span class="line">    &#125;)</span><br><span class="line">&#125;</span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">loadImg</span>(<span class="params">el</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span>(!el.src)&#123;</span><br><span class="line">        <span class="keyword">var</span> source = el.dataset.src;</span><br><span class="line">        el.src = source;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="built_in">window</span>.onload = <span class="built_in">window</span>.onscroll = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123; <span class="comment">//onscroll()在滚动条滚动的时候触发</span></span><br><span class="line">    check();</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
</li>
<li><p>通过 webpack 按需加载代码，提取第三库代码，减少 ES6 转为 ES5 的冗余代码</p>
<ul>
<li>根据文件内容生成文件名，结合 import 动态引入组件实现按需加载</li>
<li>提取第三方库：由于引入的第三方库一般都比较稳定，不会经常改变。所以将它们单独提取出来，作为长期缓存是一个更好的选择。 这里需要使用 webpack4 的 splitChunk 插件 cacheGroups 选项</li>
<li>减少 ES6 转为 ES5 的冗余代码：Babel 转化后的代码想要实现和原来代码一样的功能需要借助一些帮助函数</li>
</ul>
</li>
<li><p>减少重排和重绘</p>
<ul>
<li>重排：当改变 DOM 元素位置或大小时，会导致浏览器重新生成渲染树，这个过程叫重排（重新生成渲染数）</li>
<li>重绘：当重新生成渲染树后，就要将渲染树每个节点绘制到屏幕，这个过程叫重绘 （重排会导致重绘，重绘不会导致重排）</li>
<li>发生重排：<ul>
<li>添加或删除可见的 DOM 元素</li>
<li>元素位置改变</li>
<li>元素尺寸改变</li>
<li>内容改变</li>
<li>浏览器窗口尺寸改变</li>
</ul>
</li>
<li>发生重绘：<ul>
<li>修改背景颜色，边框颜色，字体颜色等</li>
</ul>
</li>
<li>如何避免重排和重绘：<ul>
<li>用 JavaScript 修改样式时，最好不要直接写样式，而是替换 class 来改变样式</li>
</ul>
</li>
</ul>
</li>
<li><p>使用事件委托</p>
<ul>
<li> 事件委托利用了事件冒泡，只指定一个事件处理程序，就可以管理某一类型的所有事件。所有用到按钮的事件（多数鼠标事件和键盘事件）都适合采用事件委托技术， 使用事件委托可以节省内存</li>
</ul>
</li>
<li><p>降低css选择器的复杂性</p>
<ul>
<li>浏览器读取选择器，遵循的原则是从选择器的右边到左边读取 </li>
</ul>
</li>
</ul>
<h3 id="性能优化实战"><a href="#性能优化实战" class="headerlink" title="性能优化实战"></a>性能优化实战</h3><p><img src="/blog/images/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96%E5%AE%9E%E6%88%98.jpg" alt="性能优化实战" title="性能优化实战"></p>
<h3 id="DNS解析，NDS预解析优化"><a href="#DNS解析，NDS预解析优化" class="headerlink" title="DNS解析，NDS预解析优化"></a>DNS解析，NDS预解析优化</h3><ul>
<li><p>DNS解析过程：</p>
<ul>
<li>查找浏览器缓存<ul>
<li>浏览器会检查缓存中有没有这个域名对应的解析过的IP地址，如果缓存中有，这个解析过程就将结束。浏览器缓存域名也是有限制的，不仅浏览器缓存大小有限制，而且缓存的时间也有限制，通常情况下为几分钟到几小时不等。这个缓存时间太长和太短都不好，如果缓存时间太长，一旦域名被解析到的IP有变化，会导致被客户端缓存的域名无法解析到变化后的IP地址，以致该域名不能正常解析，这段时间内有可能会有一部分用户无法访问网站。如果时间设置太短，会导致用户每次访问网站都要重新解析一次域名</li>
</ul>
</li>
<li>查找系统缓存<ul>
<li>如果用户的浏览器缓存中没有，浏览器会查找操作系统缓存中是否有这个域名对应的DNS解析结果。其实操作系统也会有一个域名解析的过程，在Windows中可以通过C:\Windows\System32\drivers\etc\hosts文件来设置，你可以将任何域名解析到任何能够访问的IP地址。如果你在这里指定了一个域名对应的IP地址，那么浏览器会首先使用这个IP地址。例如，我们在测试时可以将一个域名解析到一台测试服务器上，这样不用修改任何代码就能测试到单独服务器上的代码的业务逻辑是否正确。正是因为有这种本地DNS解析的规程，所以黑客就有可能通过修改你的域名解析来把特定的域名解析到它指定的IP地址上，导致这些域名被劫持</li>
</ul>
</li>
<li>查找路由器缓存<ul>
<li>如果系统缓存中也找不到，那么查询请求就会发向路由器，它一般会有自己的DNS缓存</li>
</ul>
</li>
<li>查找ISP DNS 缓存<ul>
<li>运气实在不好，就只能查询ISP DNS 缓存服务器了。在我们的网络配置中都会有”DNS服务器地址”这一项，操作系统会把这个域名发送给这里设置的DNS，也就是本地区的域名服务器，通常是提供给你接入互联网的应用提供商。这个专门的域名解析服务器性能都会很好，它们一般都会缓存域名解析结果，当然缓存时间是受域名的失效时间控制的，一般缓存空间不是影响域名失效的主要因素。大约80%的域名解析都到这里就已经完成了，所以ISP DNS主要承担了域名的解析工作</li>
</ul>
</li>
<li>迭代查询<ul>
<li>最无奈的情况发生了, 在前面都没有办法命中的DNS缓存的情况下，(1)本地域名服务器即将该请求转发到互联网上的根域名服务器（即一个完整域名最后面的那个点，通常省略不写）。(2)根域名服务器将所要查询域名中的顶级域（假设要查询ke.qq.com，该域名的顶级域就是com）的服务器IP地址返回到本地DNS。(3) 本地DNS根据返回的IP地址，再向顶级域（就是com域）发送请求。(4) com域服务器再将域名中的二级域（即ke.qq.com中的qq）的IP地址返回给本地DNS。(5) 本地DNS再向二级域发送请求进行查询。(6) 之后不断重复这样的过程，直到本地DNS服务器得到最终的查询结果，并返回到主机。这时候主机才能通过域名访问该网站</li>
</ul>
</li>
</ul>
</li>
<li><p>前端优化与DNS有关的就是两点：减少DNS查找，避免重定向；进行DNS的预取（DNS Prefetching）</p>
</li>
<li><p>减少DNS查找，避免重定向：浏览器DNS缓存 、计算机DNS缓存、 服务器DNS缓存、使用Keep-Alive特性 来减少DNS查找</p>
</li>
<li><p>DNS Prefetching 是让具有此属性的域名不需要用户点击链接就在后台解析，而域名解析和内容载入是串行的网络操作，所以这个方式能 减少用户的等待时间，提升用户体验。</p>
</li>
<li><p>默认情况下浏览器会对页面中和当前域名（正在浏览网页的域名）不在同一个域的域名进行预获取，并且缓存结果，这就是隐式的 DNS Prefetch。如果想对页面中没有出现的域进行预获取，那么就要使用显示的 DNS Prefetch 了</p>
</li>
<li><p>目前大多数浏览器已经支持此属性</p>
</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// DNS Prefetch 应该尽量的放在网页的前面，推荐放在 &lt;meta charset=&quot;UTF-8&quot;&gt; 后面</span></span><br><span class="line"></span><br><span class="line">&lt;meta http-equiv=<span class="string">&quot;x-dns-prefetch-control&quot;</span> content=<span class="string">&quot;on&quot;</span> /&gt;  <span class="comment">// 通过用meta信息来告知浏览器, 我这页面要做DNS预解析</span></span><br><span class="line">&lt;link href=<span class="string">&quot;&quot;</span> rel=<span class="string">&quot;dns-prefetch&quot;</span>&gt;&lt;<span class="regexp">/link&gt;                   /</span><span class="regexp">/ 使用link标签来强制对DNS做预解析</span></span><br><span class="line"><span class="regexp">&lt;link rel=&quot;dns-prefetch&quot; href=&quot;/</span><span class="regexp">/www.zhix.net&quot; /</span>&gt;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 虽然使用 DNS Prefetch 能够加快页面的解析速度，但是也不能滥用，因为有开发者指出 禁用DNS 预读取能节省每月100亿的DNS查询</span></span><br><span class="line"><span class="comment">// 禁止隐式 DNS prefetch</span></span><br><span class="line">&lt;meta http-equiv=<span class="string">&quot;x-dns-prefetch-control&quot;</span> content=<span class="string">&quot;off&quot;</span>&gt;</span><br></pre></td></tr></table></figure>
<ul>
<li>案例<br><img src="/blog/images/%E6%B7%98%E5%AE%9D.png" alt="淘宝" title="淘宝"><br><img src="/blog/images/%E6%94%AF%E4%BB%98%E5%AE%9D.png" alt="支付宝" title="支付宝"></li>
</ul>
<h3 id="TCP链接优化（很复杂，暂时没有搞懂）"><a href="#TCP链接优化（很复杂，暂时没有搞懂）" class="headerlink" title="TCP链接优化（很复杂，暂时没有搞懂）"></a>TCP链接优化（很复杂，暂时没有搞懂）</h3><ul>
<li>参考链接：<a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/121056616">https://zhuanlan.zhihu.com/p/121056616</a></li>
</ul>

      
    </div>
    <div class="article-footer">
      <!-- <blockquote class="mt-2x"> -->
  <!-- <ul class="post-copyright list-unstyled">
    
    <li class="post-copyright-link hidden-xs">
      <strong>本文链接：</strong>
      <a href="https://gitee.com/Yu-Luoboke/2021/04/23/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/" title="前端性能优化" target="_blank" rel="external">https://gitee.com/Yu-Luoboke/2021/04/23/%E5%89%8D%E7%AB%AF%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/</a>
    </li>
    
    <li class="post-copyright-license">
      <strong>版权声明： </strong> 本博客所有文章除特别声明外，均采用 <a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN协议</a> 许可协议。转载请注明出处！
    </li>
  </ul> -->
<!-- </blockquote> -->


<!-- <div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="http://yu-luoboke.gitee.io/blog" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="/blog/images/avatar.jpg" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="http://yu-luoboke.gitee.io/blog" target="_blank"><span class="text-dark">雨落</span><small class="ml-1x">前端开发-奋斗青年</small></a></h3>
        <div>前端经验总结。</div>
      </div>
    </figure>
  </div>
</div> -->


    </div>
  </article>
  
    

  
</div>

  <nav class="bar bar-footer clearfix" data-stick-bottom>
  <div class="bar-inner">
  
  <ul class="pager pull-left">
    
    <li class="prev">
      <a href="/blog/2021/10/23/%E5%B7%A5%E4%BD%9C%E5%8A%9F%E8%83%BD%E5%BD%92%E7%BA%B3-md/" title="工作功能归纳.md"><i class="icon icon-angle-left" aria-hidden="true"></i><span>&nbsp;&nbsp;上一篇</span></a>
    </li>
    
    
    <li class="next">
      <a href="/blog/2021/03/31/%E7%A7%BB%E5%8A%A8%E7%AB%AF%E9%80%82%E9%85%8D/" title="移动端适配"><span>下一篇&nbsp;&nbsp;</span><i class="icon icon-angle-right" aria-hidden="true"></i></a>
    </li>
    
    
  </ul>
  
  
  
  <div class="bar-right">
    
  </div>
  </div>
</nav>
  


</main>

  <footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
	
	
    <ul class="social-links">
    	
        <li><a href="http://yu-luoboke.gitee.io/blog" target="_blank" title="Github" ><i class="icon icon-github"></i></a></li>
        
    </ul>

    <div class="copyright">
    	
        &copy; 2024 lianghongming
        
        <div class="publishby">
        	Theme by <a href="https://gitee.com/Yu-Luoboke/blog" target="_blank"> blog </a>base on <a href="https://gitee.com/Yu-Luoboke/blog" target="_blank">pure</a>.
        </div>
    </div>
</footer>
  <script src="//cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>

<script src="/blog/js/plugin.min.js"></script>


<script src="/blog/js/application.js"></script>


    <script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: '文章',
            PAGES: '页面',
            CATEGORIES: '分类',
            TAGS: '标签',
            UNTITLED: '(未命名)',
        },
        ROOT_URL: '/blog/',
        CONTENT_URL: '/blog/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>

<script src="/blog/js/insight.js"></script>






   









</body>
</html>